@use 'sass:color';
@use 'sass:map';

@use './shared' as *;
@use './design' as *;

$button: () !default;
$button: map.merge(
  (
    color: get-css-var('content-color-base'),
    color-hover: get-css-var('color-primary-light-2'),
    color-focus: get-css-var('color-primary-light-2'),
    color-active: get-css-var('color-primary-dark-1'),
    color-disabled: get-css-var('content-color-disabled'),
    bg-color: get-css-var('fill-color-base'),
    bg-color-hover: get-css-var('button-bg-color'),
    bg-color-focus: get-css-var('button-bg-color'),
    bg-color-active: get-css-var('button-bg-color'),
    bg-color-disabled: get-css-var('fill-color-background'),
    b-color: get-css-var('border-color-base'),
    b-color-hover: get-css-var('color-primary-light-2'),
    b-color-focus: get-css-var('color-primary-light-2'),
    b-color-active: get-css-var('color-primary-dark-1'),
    b-color-disabled: get-css-var('border-color-light-1'),
    border: get-css-var('border-shape') get-css-var('button-b-color'),
    radius: get-css-var('radius-base'),
    pulse-s-color: get-css-var('color-primary-base'),
    pulse-opacity: 60%,
    pulse-size: 6px,
    pulse-duration: 800ms,
    pulse-timing: ease,
    height: 32px,
    v-padding: 0,
    h-padding: 14px,
    font-size: get-css-var('font-size-base'),
    series-span: 8px,
    icon-span: 6px,
    d-color-typed: rgba($color-white, 50%),
    badge-color: get-css-var('color-white'),
    badge-bg-color: get-css-var('color-error-base'),
    badge-b-color: get-css-var('color-error-base')
  ),
  $button
);

.#{$namespace}-button {
  &-vars {
    @include define-preset-values('button', $button);
  }

  $self: &;

  @mixin disabled($selector) {
    @at-root {
      #{$self}--disabled#{$selector} {
        &,
        &:hover,
        &:active,
        &.active {
          @content;
        }
      }
    }
  }

  @mixin define-button-style($style-map) {
    @include define-preset-style('button', $style-map);
  }

  @include basis;

  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: get-css-var('button-height');
  padding: get-css-var('button-v-padding') get-css-var('button-h-padding');
  font-weight: 400;
  line-height: 1;
  color: get-css-var('button-color');
  white-space: nowrap;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
  background-color: get-css-var('button-bg-color');
  border: get-css-var('button-border');
  border-radius: get-css-var('button-radius');
  outline: 0;
  transition: get-css-var('transition-color'), get-css-var('transition-background'),
    get-css-var('transition-border'), get-css-var('transition-shadow');

  &:hover {
    color: get-css-var('button-color-hover');
    background-color: get-css-var('button-bg-color-hover');
    border-color: get-css-var('button-b-color-hover');
    outline: 0;
  }

  &:focus {
    color: get-css-var('button-color-focus');
    background-color: get-css-var('button-bg-color-focus');
    border-color: get-css-var('button-b-color-focus');
    outline: 0;
  }

  &:active {
    color: get-css-var('button-color-active');
    background-color: get-css-var('button-bg-color-active');
    border-color: get-css-var('button-b-color-active');
  }

  @include disabled('') {
    color: get-css-var('button-color-disabled');
    cursor: not-allowed;
    background-color: get-css-var('button-bg-color-disabled');
    border-color: get-css-var('button-b-color-disabled');
  }

  &--block {
    display: flex;
    width: 100%;
  }

  &:not(#{&}--block) + &:not(#{&}--block) {
    margin-inline-start: get-css-var('button-series-span');
  }

  &--small {
    @include define-preset-values(
      'button',
      (
        height: 24px,
        h-padding: 10px
      )
    );
  }

  &--large {
    @include define-preset-values(
      'button',
      (
        height: 40px,
        h-padding: 20px
      )
    );
  }

  &::after {
    position: absolute;
    inset: 0;
    display: block;
    pointer-events: none;
    content: '';
    background-color: transparent;
    border-radius: inherit;
    animation-duration: get-css-var('button-pulse-duration');
    animation-timing-function: get-css-var('button-pulse-timing');
    animation-iteration-count: 1;
  }

  &--pulsing::after {
    animation-name:
      #{$namespace}-button-pulse,
      #{$namespace}-button-pulse-opacity;

    @keyframes #{$namespace}-button-pulse {
      0% {
        box-shadow: 0 0 1px 0 get-css-var('button-pulse-s-color');
      }

      100% {
        box-shadow: 0 0 1px get-css-var('button-pulse-size') get-css-var('button-pulse-s-color');
      }
    }

    @keyframes #{$namespace}-button-pulse-opacity {
      0% {
        opacity: get-css-var('button-pulse-opacity');
      }

      100% {
        opacity: 0%;
      }
    }
  }

  &--dashed {
    border-style: dashed;

    &,
    &:hover,
    &:focus,
    &:active,
    &.active {
      background-color: transparent;
    }
  }

  &--text {
    border-color: transparent;

    &::after {
      display: none;
    }

    &,
    &:hover,
    &:focus,
    &:active,
    &.active {
      background-color: transparent;
      border-color: transparent;
    }
  }

  &--ghost {
    @include define-preset-values(
      'button',
      (
        color: rgba($color-white, 0.8),
        bg-color: transparent,
        bg-color-hover: transparent,
        bg-color-focus: transparent,
        bg-color-active: transparent,
        bg-color-disabled: transparent,
        b-color: rgba($color-white, 0.6)
      )
    );

    @include define-button-style(
      (
        color-hover: 'color-primary-base',
        color-focus: 'color-primary-base',
        color-active: 'color-primary-base',
        color-disabled: 'content-color-disabled',
        b-color-hover: 'color-primary-base',
        b-color-active: 'color-primary-base',
        b-color-disabled: 'content-color-disabled'
      )
    );
  }

  &--text#{&}--ghost {
    border-color: transparent;
  }

  $d-color: get-css-var('button-d-color-typed');

  @each $type in $types {
    @at-root {
      &--#{$type} {
        @include define-button-style(
          (
            color: 'color-white',
            color-hover: 'color-white',
            color-focus: 'color-white',
            color-active: 'color-white',
            color-disabled: 'content-color-disabled',
            bg-color: 'color' $type 'base',
            bg-color-hover: 'color' $type 'light-2',
            bg-color-focus: 'color' $type 'light-2',
            bg-color-active: 'color' $type 'dark-1',
            bg-color-disabled: 'fill-color-background',
            b-color: 'color' $type 'base',
            b-color-hover: 'color' $type 'light-2',
            b-color-focus: 'color' $type 'light-2',
            b-color-active: 'color' $type 'dark-1',
            b-color-disabled: 'border-color-light-1',
            pulse-s-color: 'color' $type 'dark-1'
          )
        );
      }

      &--#{$type}#{&}--simple {
        @include define-button-style(
          (
            color: 'color' $type 'base',
            color-hover: 'color' $type 'base',
            color-focus: 'color-white',
            color-active: 'color-white',
            color-disabled: 'content-color-disabled',
            bg-color: 'color' $type 'opacity-8',
            bg-color-hover: 'color' $type 'opacity-7',
            bg-color-focus: 'color' $type 'opacity-3',
            bg-color-active: 'color' $type 'opacity-3',
            bg-color-disabled: 'fill-color-background',
            b-color: 'color' $type 'opacity-4',
            b-color-hover: 'color' $type 'opacity-4',
            b-color-focus: 'color' $type 'opacity-3',
            b-color-active: 'color' $type 'opacity-3',
            b-color-disabled: 'border-color-light-1'
          )
        );
      }

      &--#{$type}#{&}--ghost {
        @include define-preset-values(
          'button',
          (
            bg-color: transparent,
            bg-color-hover: rgba($color-white, 0.1),
            bg-color-focus: rgba($color-white, 0.1),
            bg-color-active: rgba($color-white, 0.2),
            bg-color-disabled: transparent
          )
        );

        @include define-button-style(
          (
            color: 'color' $type 'base',
            color-hover: 'color' $type 'base',
            color-focus: 'color' $type 'base',
            color-active: 'color' $type 'base',
            color-disabled: 'content-color-disabled',
            b-color-disabled: 'content-color-disabled'
          )
        );
      }

      &--#{$type}#{&}--text,
      &--#{$type}#{&}--dashed {
        @include define-button-style(
          (
            color: 'color' $type 'base',
            color-hover: 'color' $type 'light-2',
            color-focus: 'color' $type 'light-2',
            color-active: 'color' $type 'dark-1'
          )
        );
      }

      &-group &--#{$type} {
        &:first-child {
          border-inline-end-color: $d-color;
        }

        &:last-child {
          border-inline-start: $d-color;
        }

        &:not(:first-child, :last-child) {
          border-inline-color: $d-color;
        }
      }
    }
  }

  &--text#{&}--disabled {
    &,
    &:hover,
    &:active,
    &.active {
      background-color: transparent;
      border-color: transparent;
    }
  }

  &--circle {
    border-radius: get-css-var('button-height');
  }

  &--loading {
    position: relative;
    pointer-events: none;
    cursor: default;

    &::before {
      position: absolute;
      inset: -1px;
      z-index: 1;
      pointer-events: none;
      content: '';
      background-color: get-css-var('color-white');
      border-radius: inherit;
      opacity: 25%;
      transition: get-css-var('transition-opacity');
    }
  }

  &__icon {
    display: flex;
    align-items: center;
    margin-inline-end: get-css-var('button-icon-span');
  }

  &--icon-only {
    width: get-css-var('button-height');
    padding: 0;
  }

  &--icon-only &__icon {
    margin: 0;
  }

  &--icon-only#{&}--small {
    width: get-css-var('button-height');
  }

  &--icon-only#{&}--large {
    width: get-css-var('button-height');
  }

  &__badge {
    margin-inline-start: 8px;
    pointer-events: none;

    .#{$namespace}-badge__content {
      color: get-css-var('button-badge-color');
      background-color: get-css-var('button-badge-bg-color');
      box-shadow: get-css-var('shadow-border') get-css-var('button-badge-b-color');
    }
  }

  @each $type in $types {
    &__badge--#{$type} {
      @include define-button-style(
        (
          badge-color: 'button-bg-color',
          badge-bg-color: 'button-color',
          badge-b-color: 'button-color'
        )
      );
    }

    &--ghost &__badge--#{$type} {
      @include define-button-style(
        (
          badge-color: 'button-color',
          badge-bg-color: transparent
        )
      );
    }

    &--simple &__badge--#{$type},
    &--text &__badge--#{$type},
    &--dashed &__badge--#{$type} {
      @include define-button-style(
        (
          badge-color: 'color-white'
        )
      );
    }
  }

  &__badge--disabled .#{$namespace}-badge__content {
    @include define-button-style(
      (
        badge-color: 'button-color-disabled',
        badge-bg-color: 'button-bg-color-disabled',
        badge-b-color: 'button-b-color-disabled'
      )
    );
  }

  @at-root {
    &-group {
      @include basis;

      display: inline-flex;
      align-items: center;

      #{$self} {
        @include define-preset-values(
          'button',
          (
            series-span: 0
          )
        );

        border-radius: 0;

        &:hover,
        &:focus {
          z-index: 1;
        }

        &:active,
        &--active {
          z-index: 2;
        }

        &--first {
          margin-inline-end: 0;

          @include logical-radius(get-css-var('button-radius') 0 0 get-css-var('button-radius'));
        }

        &--last {
          margin-inline-end: 0;

          @include logical-radius(0 get-css-var('button-radius') get-css-var('button-radius') 0);
        }

        &:not(#{$self}--last) {
          margin-inline-end: -1px;
        }
      }

      &--circle {
        #{$self} {
          &--first {
            @include logical-radius(get-css-var('button-height') 0 0 get-css-var('button-height'));
          }

          &--last {
            @include logical-radius(0 get-css-var('button-height') get-css-var('button-height') 0);
          }
        }
      }
    }
  }
}
